package gorpc

import (
	"sync"
)

// RPCMessage 表示一个RPC消息
type RPCMessage struct {
	mu    sync.RWMutex
	id    string
	data  []byte
	props map[string]string
	level int
}

// NewMessage 创建新的消息实例
func NewMessage() *RPCMessage {
	return &RPCMessage{
		props: make(map[string]string),
	}
}

// NewMessageWithID 创建指定ID的消息实例
func NewMessageWithID(id string) *RPCMessage {
	msg := NewMessage()
	msg.SetMessageID(id)
	return msg
}

// GetMessageID 获取消息ID
func (m *RPCMessage) GetMessageID() string {
	m.mu.RLock()
	defer m.mu.RUnlock()
	return m.id
}

// SetMessageID 设置消息ID
func (m *RPCMessage) SetMessageID(id string) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.id = id
}

// GetMessage 获取消息体
func (m *RPCMessage) GetMessage() []byte {
	m.mu.RLock()
	defer m.mu.RUnlock()

	// 返回数据的副本以避免外部修改
	if m.data == nil {
		return nil
	}

	result := make([]byte, len(m.data))
	copy(result, m.data)
	return result
}

// SetMessage 设置消息体
func (m *RPCMessage) SetMessage(data []byte) {
	m.mu.Lock()
	defer m.mu.Unlock()

	if data == nil {
		m.data = nil
		return
	}

	// 创建数据的副本以避免外部修改
	m.data = make([]byte, len(data))
	copy(m.data, data)
}

// GetProps 获取消息属性
func (m *RPCMessage) GetProps() map[string]string {
	m.mu.RLock()
	defer m.mu.RUnlock()

	// 返回属性的副本以避免外部修改
	props := make(map[string]string, len(m.props))
	for k, v := range m.props {
		props[k] = v
	}
	return props
}

// SetProps 设置消息属性
func (m *RPCMessage) SetProps(props map[string]string) {
	m.mu.Lock()
	defer m.mu.Unlock()

	m.props = make(map[string]string, len(props))
	for k, v := range props {
		m.props[k] = v
	}
}

// GetProp 获取单个属性
func (m *RPCMessage) GetProp(key string) string {
	m.mu.RLock()
	defer m.mu.RUnlock()
	return m.props[key]
}

// SetProp 设置单个属性
func (m *RPCMessage) SetProp(key, value string) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.props[key] = value
}

// SetErrorMessage 设置错误消息
func (m *RPCMessage) SetErrorMessage(errMsg string) {
	m.SetProp("error", errMsg)
}

// GetErrorMessage 获取错误消息
func (m *RPCMessage) GetErrorMessage() string {
	return m.GetProp("error")
}

// IsError 检查是否存在错误
func (m *RPCMessage) IsError() bool {
	return m.GetErrorMessage() != ""
}

// GetLevel 获取消息级别
func (m *RPCMessage) GetLevel() int {
	m.mu.RLock()
	defer m.mu.RUnlock()
	return m.level
}

// SetLevel 设置消息级别
func (m *RPCMessage) SetLevel(level int) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.level = level
}
